package main

import (
	"fmt"
	"sync"
	"time"
)

type Parallel struct {
	num int
	sig chan struct{}
	wg  sync.WaitGroup
}

func NewParallel(num int) *Parallel {
	return &Parallel{
		sig: make(chan struct{}, num),
		num: num,
	}
}

func (this *Parallel) Add() {
	this.wg.Add(1)
	this.sig <- struct{}{}
}

func (this *Parallel) Done() {
	<-this.sig
	this.wg.Done()
}

func (this *Parallel) Wait() {
	this.wg.Wait()
}

func main() {
	p := NewParallel(4)

	for i := 0; i < 10; i++ {
		p.Add()
		go func(idx int) {
			defer p.Done()
			fmt.Println("Complete:", idx)
			time.Sleep(time.Second)
		}(i)
	}

	p.Wait()
}
